#Boa:Frame:dbBackup

import wx
import MySQLdb
import MySQLdb.cursors
import servers
import utiles
import os
import subprocess

#directorios del sistema con aplicaciones necesarias para la correcta
#ejecucion de este script. "backup" es un directorio con el resultado
dirMYSQL = "\\wamp\\bin\\mysql\\mysql5.0.51b\\bin\\"
dirBACKUP = "backup\\"
dirWINXPsp = "\\Archivos de programa\\7-Zip\\"
dirWINXPen = "\\Program Files\\7-Zip\\"

ApagarAlTerminar = False

def create(parent):
    return dbBackup(parent)

[wxID_DBBACKUP, wxID_DBBACKUPBUTTON1, wxID_DBBACKUPBUTTON3, 
 wxID_DBBACKUPCHECKBOX1, wxID_DBBACKUPCHECKBOX2, wxID_DBBACKUPCHECKBOX3, 
 wxID_DBBACKUPDIRECTORIO, wxID_DBBACKUPPANEL1, wxID_DBBACKUPPASSWORD, 
 wxID_DBBACKUPSTATICLINE1, wxID_DBBACKUPSTATICLINE2, wxID_DBBACKUPSTATICTEXT1, 
 wxID_DBBACKUPSTATICTEXT2, wxID_DBBACKUPSTATICTEXT3, wxID_DBBACKUPSTATICTEXT4, 
 wxID_DBBACKUPSTATICTEXT5, wxID_DBBACKUPSTATICTEXT6, wxID_DBBACKUPSTATICTEXT7, 
 wxID_DBBACKUPSTATICTEXT8, wxID_DBBACKUPSTATICTEXT9, wxID_DBBACKUPUSUARIO, 
] = [wx.NewId() for _init_ctrls in range(21)]

def verificarArchivosNecesarios():
    resultado = True
    #se verifica la existencia de los archivos necesarios para la ejecucion
    #del backup: wamp instalado con mysqldum y 7-zip para comprimir archivos
    if not os.path.lexists(dirWINXPsp) and not os.path.lexists(dirWINXPen):
            aux1 = "Debe instalar 7-ZIP en su sistema\n"
            aux2 = "Descarguelo de http://www.7-zip.org/"
            mensaje = aux1 + aux2
            utiles.mensaje(None,mensaje)
            resultado = False
    directorio = dirBACKUP + "7z.exe"
    if not os.path.exists(directorio):
        aux1 = "No existe el archivo 7Z.EXE en el directorio BACKUP\n"
        aux2 = "Es necesario para comprimir los datos resguardados"
        mensaje = aux1 + aux2
        utiles.mensaje(None,mensaje)
        resultado = False
    directorio = dirMYSQL + "mysqldump.exe"
    if not os.path.exists(directorio):
        aux1 = "No existe el archivo MYSQLDUMP.EXE para el backup\n"
        aux2 = "Verifique la instalacion de WAMP y la carpeta MySQL"
        mensaje = aux1 + aux2
        utiles.mensaje(None,mensaje)
        resultado = False
    return resultado

class dbBackup(wx.Frame):
    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Frame.__init__(self, id=wxID_DBBACKUP, name='dbBackup', parent=prnt,
              pos=wx.Point(377, 136), size=wx.Size(326, 303),
              style=wx.DEFAULT_FRAME_STYLE, title='dbBackup')
        self.SetClientSize(wx.Size(318, 276))

        self.panel1 = wx.Panel(id=wxID_DBBACKUPPANEL1, name='panel1',
              parent=self, pos=wx.Point(0, 0), size=wx.Size(318, 276),
              style=wx.TAB_TRAVERSAL)
        self.panel1.Show(True)

        self.staticText1 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT1,
              label='Usuario', name='staticText1', parent=self.panel1,
              pos=wx.Point(24, 16), size=wx.Size(36, 13), style=0)

        self.staticText2 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT2,
              label='Contrase\xf1a', name='staticText2', parent=self.panel1,
              pos=wx.Point(168, 16), size=wx.Size(56, 13), style=0)

        self.usuario = wx.TextCtrl(id=wxID_DBBACKUPUSUARIO, name='usuario',
              parent=self.panel1, pos=wx.Point(24, 32), size=wx.Size(128, 21),
              style=0, value='')

        self.password = wx.TextCtrl(id=wxID_DBBACKUPPASSWORD, name='password',
              parent=self.panel1, pos=wx.Point(168, 32), size=wx.Size(128, 21),
              style=wx.TE_PASSWORD, value='')
        self.password.SetToolTipString('password')

        self.staticText4 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT4,
              label='Bases de datos', name='staticText4', parent=self.panel1,
              pos=wx.Point(24, 64), size=wx.Size(73, 13), style=0)

        self.checkBox1 = wx.CheckBox(id=wxID_DBBACKUPCHECKBOX1,
              label='ERPSussan', name='checkBox1', parent=self.panel1,
              pos=wx.Point(24, 88), size=wx.Size(70, 13), style=0)
        self.checkBox1.SetValue(True)

        self.checkBox2 = wx.CheckBox(id=wxID_DBBACKUPCHECKBOX2,
              label='Sincronizar', name='checkBox2', parent=self.panel1,
              pos=wx.Point(24, 112), size=wx.Size(70, 13), style=0)
        self.checkBox2.SetValue(False)

        self.staticLine2 = wx.StaticLine(id=wxID_DBBACKUPSTATICLINE2,
              name='staticLine2', parent=self.panel1, pos=wx.Point(121, 64),
              size=wx.Size(1, 88), style=0)

        self.checkBox3 = wx.CheckBox(id=wxID_DBBACKUPCHECKBOX3,
              label='Apagar el sistema al terminar', name='checkBox3',
              parent=self.panel1, pos=wx.Point(136, 88), size=wx.Size(160, 16),
              style=0)
        self.checkBox3.SetValue(False)

        self.staticLine1 = wx.StaticLine(id=wxID_DBBACKUPSTATICLINE1,
              name='staticLine1', parent=self.panel1, pos=wx.Point(25, 160),
              size=wx.Size(271, 2), style=0)

        self.staticText3 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT3,
              label='Directorio del backup', name='staticText3',
              parent=self.panel1, pos=wx.Point(24, 168), size=wx.Size(272, 13),
              style=0)

        self.directorio = wx.TextCtrl(id=wxID_DBBACKUPDIRECTORIO,
              name='directorio', parent=self.panel1, pos=wx.Point(24, 184),
              size=wx.Size(272, 21), style=0, value='erpsussan/backup')
        self.directorio.Enable(False)

        self.button1 = wx.Button(id=wxID_DBBACKUPBUTTON1, label='Aceptar',
              name='button1', parent=self.panel1, pos=wx.Point(128, 232),
              size=wx.Size(75, 23), style=0)
        self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
              id=wxID_DBBACKUPBUTTON1)

        self.button3 = wx.Button(id=wxID_DBBACKUPBUTTON3, label='Salir',
              name='button3', parent=self.panel1, pos=wx.Point(216, 232),
              size=wx.Size(75, 23), style=0)
        self.button3.Bind(wx.EVT_BUTTON, self.OnButton3Button,
              id=wxID_DBBACKUPBUTTON3)

        self.staticText5 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT5, label='',
              name='staticText5', parent=self.panel1, pos=wx.Point(24, 182),
              size=wx.Size(272, 13), style=0)
        self.staticText5.Show(False)

        self.staticText6 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT6, label='',
              name='staticText6', parent=self.panel1, pos=wx.Point(24, 197),
              size=wx.Size(272, 13), style=0)
        self.staticText6.Show(False)

        self.staticText7 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT7, label='',
              name='staticText7', parent=self.panel1, pos=wx.Point(24, 212),
              size=wx.Size(272, 13), style=0)
        self.staticText7.Show(False)

        self.staticText8 = wx.StaticText(id=wxID_DBBACKUPSTATICTEXT8, label='',
              name='staticText8', parent=self.panel1, pos=wx.Point(136, 136),
              size=wx.Size(0, 13), style=0)

    def __init__(self, parent):
        if not verificarArchivosNecesarios():
            exit()
        self.sucursalnro,self.sucursalnombre = utiles.datosSucursal()
        self.sucursalnro = int(self.sucursalnro)-1
        print "Sucursal",self.sucursalnombre
        
        self._init_ctrls(parent)
        self.usuario.SetValue(servers.vpn_user[self.sucursalnro])
        self.password.SetValue(servers.vpn_passwd[self.sucursalnro])
        self.button1.SetFocus()
        #si es la casa matriz, alli esta instalada la base de datos
        #sincronizar y por lo tanto se muestra tildada la opcion correspondiente
        if utiles.getSucursalActiva() == "1":
            self.checkBox2.SetValue(True)

    def OnButton1Button(self, event):
        #verificando casillas marcadas: 
        #debe hacerse backup de al menos una base de datos
        if not self.checkBox1.GetValue() and not self.checkBox2.GetValue():
            utiles.mensaje(None,"Debe seleccionar al menos una base de datos")
        else:
            #Logearse al mysql y verificar la conexion de las bases de datos
            #seleccionadas -> si hay problemas, avisar y volver al principio
            error = 0
            db_user = servers.vpn_user[self.sucursalnro]
            db_passwd = servers.vpn_passwd[self.sucursalnro]
            if self.checkBox1.GetValue():
                db_name = servers.vpn_db_name[self.sucursalnro]
                try:
                    self.verificarConexionBD(db_user,db_passwd,db_name)
                    print "Conexion exitosa"
                except:
                    aux1 = "ERROR: no se pudo conectar con la BD ERPSUSSAN.\n"
                    aux2 = "Verifique: existe? wamp activo? esta autorizado?"
                    mensaje = aux1 + aux2
                    utiles.mensaje(None,mensaje)
                    print "Conexion fallida"
                    error += 1
                    self.checkBox1.SetValue(False)
            if self.checkBox2.GetValue():
                db_name = "sincronizar"
                try:
                    db_user = servers.user_remote
                    db_passwd = servers.passwd_remote
                    self.verificarConexionBD(db_user,db_passwd,db_name)
                    print "Conexion exitosa"
                except:
                    aux1 = "ERROR: no se pudo conectar con la BD SINCRONIZAR.\n"
                    aux2 = "Verifique: existe? wamp activo? esta autorizado?"
                    mensaje = aux1 + aux2
                    utiles.mensaje(None,mensaje)
                    print "Conexion fallida"
                    error += 1
                    self.checkBox2.SetValue(False)
            if error > 1:
                #si no existen ninguna de las dos bases de datos, entonces
                #no tiene sentido mantener abierta esta aplicacion y finaliza
                self.Close()
            if error == 0:
                self.ejecutarBackup()
        
    def OnButton3Button(self, event):
        #salir sin hacer nada
        self.Close()

    def verificarConexionBD(self, user, passwd, dataname):
        print "Intentando conectar a la BD",dataname
        #host,user,passwd,name_database
        conectar=MySQLdb.connect(host=servers.host, 
                    user=user, passwd=passwd, db=dataname, 
                    cursorclass=MySQLdb.cursors.DictCursor)
        cursor=conectar.cursor()

    def ejecutarBackup(self):
        self.directorio.Show(False)
        self.button1.Show(False)
        self.button3.Show(False)
        self.staticText3.SetLabel("")
        self.staticText5.Show(True)
        self.staticText6.Show(True)
        self.staticText7.Show(True)
        self.mostrar("Ejecutando el BACKUP")

        #Iniciando ejecucion del backup
        self.mostrar("Iniciando ejecucion del backup")

        a1 = utiles.getfechaInverseTime()
        fecha = a1[0:4] + a1[5:7] + a1[8:10] + a1[11:13] + a1[14:16] + a1[17:19]

        if self.checkBox1.GetValue():
            nameFile = "erpsussan"
            self.ejecutarComandos(nameFile, fecha)
        if self.checkBox2.GetValue():
            nameFile = "sincronizar"
            self.usuario.SetValue(servers.user_remote)
            self.password.SetValue(servers.passwd_remote)
            self.ejecutarComandos(nameFile, fecha)
            
        if self.checkBox3.GetValue():
            comando = "shutdown -s -t 10"
            self.mostrar(comando)
            self.mostrar("APAGAR EL SISTEMA")
            p = subprocess.Popen(comando, shell=True)

        self.Close()

    def ejecutarComandos(self, nameFile, fecha):
        self.mostrar(nameFile)
        aux1 = dirMYSQL + "mysqldump.exe --opt"
        aux2 = " --user=" + self.usuario.GetValue()
        aux3 = " --password=" + self.password.GetValue()
        aux4 = " " + nameFile + " > "
        
        nameFile = nameFile + fecha
        aux5 = dirBACKUP + nameFile + ".sql"

        #ejecutar comando para backupear la base de datos en un "sql"
        self.mostrar("Ejecutando comando MYSQLDUMP")

        comando = aux1 + aux2 + aux3 + aux4 + aux5
        self.staticText7.SetLabel(comando)

        p = subprocess.Popen(comando, shell=True)
        p.wait()

        texto = "codigo de salida del comando MYSQLDUMP: " + str(p.returncode)
        self.mostrar(texto)
        if p.returncode != 0: self.mostrarError("BACKUP ABORTADO")
        
        aux6 = dirBACKUP + "7z.exe a " + dirBACKUP + nameFile
        aux7 = " " + dirBACKUP + nameFile + ".sql"

        #ejecutar comando para comprimir el archivo del backup
        comando = aux6 + aux7
        self.mostrar(comando)

        p = subprocess.Popen(comando, shell=True)
        p.wait()
        
        texto = "codigo de salida del comando 7Z:" + str(p.returncode)
        self.mostrar(texto)
        if p.returncode != 0: self.mostrarError("FALLA AL COMPRIMIR")
            

        #borrar el archivo "sql" original
        comando = "del " + dirBACKUP + nameFile + ".sql"
        self.mostrar(comando)

        p = subprocess.Popen(comando, shell=True)
        p.wait()
        
        texto = "codigo de salida del comando DEL: " + str(p.returncode)
        self.mostrar(texto)
        if p.returncode != 0: self.mostrarError("FALLA AL BORRAR 'sql'")

    def mostrar(self, texto):
        self.staticText3.SetLabel(self.staticText5.GetLabel())
        self.staticText5.SetLabel(self.staticText6.GetLabel())
        self.staticText6.SetLabel(self.staticText7.GetLabel())
        self.staticText7.SetLabel(texto)
        print texto
        utiles.logOperaciones(texto)

    def mostrarError(self, texto):
        utiles.mensaje(None, texto)
        exit()
